package com.zhiwei.tool;

import com.itextpdf.barcodes.BarcodeQRCode;
import com.itextpdf.io.font.PdfEncodings;
import com.itextpdf.io.image.ImageDataFactory;
import com.itextpdf.kernel.color.Color;
import com.itextpdf.kernel.color.DeviceCmyk;
import com.itextpdf.kernel.color.DeviceRgb;
import com.itextpdf.kernel.font.PdfFont;
import com.itextpdf.kernel.font.PdfFontFactory;
import com.itextpdf.kernel.geom.PageSize;
import com.itextpdf.kernel.pdf.PdfDocument;
import com.itextpdf.kernel.pdf.PdfPage;
import com.itextpdf.kernel.pdf.PdfWriter;
import com.itextpdf.kernel.pdf.canvas.PdfCanvas;
import com.itextpdf.layout.Document;
import com.itextpdf.layout.element.*;
import com.itextpdf.layout.element.Image;
import com.zhiwei.pojo.*;
import lombok.Data;
import lombok.experimental.Accessors;
import org.springframework.stereotype.Component;

import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

@Component
public class TipGener {
    public static File getInvoice(String filePath,Order order, Bill bill, Products product,
                                  Trader trader, Trader ourCompany, User sealer,
                                  User dealer) throws Exception {
        PdfWriter pdfWriter = new PdfWriter(filePath+"tip.pdf");
        PdfDocument pdfDocument = new PdfDocument(pdfWriter);
//        PageSize ps = PageSize.A4.rotate();
//        设置pageSize  比率2.833333333 毫米比
        PageSize ps = new PageSize(595F, 395.8167F);
        PdfPage pdfPage = pdfDocument.addNewPage(ps);
        PdfCanvas canvas = new PdfCanvas(pdfPage);
//        设置中心为原点
        canvas.concatMatrix(1, 0, 0, 1, ps.getWidth() / 2, ps.getHeight() / 2);
        Color grayColor = new DeviceCmyk(0.f, 0.f, 0.f, 0.875f);
        Color greenColor = new DeviceCmyk(1.f, 0.f, 1.f, 0.176f);
        Color blueColor = new DeviceCmyk(1.f, 0.156f, 0.f, 0.118f);
        Color titleColor = new DeviceRgb(130, 89, 37);
//        设置粗线
        canvas.setStrokeColor(titleColor).setLineWidth(2);
//        外框绘制
        canvas.moveTo(- ps.getWidth()/2 + 25, ps.getHeight()/2 -90)
                .lineTo(ps.getWidth()/2 - 25,ps.getHeight()/2 -90)
                .lineTo(ps.getWidth()/2 - 25,- ps.getHeight()/2 +35)
                .lineTo(- ps.getWidth()/2 + 25,- ps.getHeight()/2 +35)
                .lineTo(- ps.getWidth()/2 + 25,ps.getHeight()/2 -90).stroke();
//        标题横线绘制
        canvas.moveTo(- ps.getWidth()/2 + 150, ps.getHeight()/2 -58)
                .lineTo(ps.getWidth()/2 - 150, ps.getHeight()/2 -58).stroke();
//        设置细线
        canvas.setStrokeColor(titleColor).setLineWidth(1);
//        绘制横向线框
        canvas.moveTo(- ps.getWidth()/2 + 150, ps.getHeight()/2 -62)
                .lineTo(ps.getWidth()/2 - 150, ps.getHeight()/2 -62).stroke();
        canvas.moveTo(- ps.getWidth()/2 + 25, ps.getHeight()/2 -150)
                .lineTo(ps.getWidth()/2 - 25,ps.getHeight()/2 -150).stroke();
        canvas.moveTo(ps.getWidth()/2 - 25,- ps.getHeight()/2 +115)
                .lineTo(- ps.getWidth()/2 + 25,- ps.getHeight()/2 +115).stroke();
        canvas.moveTo(ps.getWidth()/2 - 25,- ps.getHeight()/2 +95)
                .lineTo(- ps.getWidth()/2 + 25,- ps.getHeight()/2 +95).stroke();
//        x轴坐标数组，绘制上下小横格竖线
        Integer[] smallCol = {- 248,55,75};
//          上面小格子纵向线框
        for (Integer i : smallCol) {
            canvas.moveTo(i, ps.getHeight()/2 -90)
                    .lineTo(i, ps.getHeight()/2 -150).stroke();
        }
        //          下面小格子纵向线框
        for (Integer i : smallCol) {
            canvas.moveTo( i, - ps.getHeight()/2 +95)
                    .lineTo(i, - ps.getHeight()/2 +35).stroke();
        }
//        第一条竖线
        canvas.moveTo( - ps.getWidth()/2 + 160, ps.getHeight()/2 -150)
                .lineTo(- ps.getWidth()/2 + 160, - ps.getHeight()/2 +95).stroke();
//        x轴坐标数组，绘制中间横格竖线
        Integer[] bigCol = {- 68,- 28,35,100,170,200};
//        中间大格子后面竖线
        for (Integer i : bigCol) {
            canvas.moveTo( i, ps.getHeight()/2 -150)
                    .lineTo(i, - ps.getHeight()/2 +115).stroke();
        }
//        设置表格模板字体及字体颜色
        PdfFont txtFont = PdfFontFactory.createFont(filePath+"simfang.ttf", PdfEncodings.IDENTITY_H,true);
//        设置标题并添加
        Paragraph title = new Paragraph("智为科技普通电子发票")
                .setFont(txtFont).setFontColor(titleColor)
                .setFontSize(26)
                .setFixedPosition(- ps.getWidth()/2 + 170, ps.getHeight()/2 -58,1000);
        Document document = new Document(pdfDocument);
        //设置税章图片
        Image image = new Image(ImageDataFactory.create(filePath + "seal.png"));
        image.setFixedPosition(- ps.getWidth()/2 + 250, ps.getHeight()/2 -100)
                .setMaxHeight(70);
        //添加税章与标题
        document.add(image).add(title);

        //获取各个标题名称
        ArrayList<txtName> txtList = getTitleList();

        //写入标题
        for (txtName txtName : txtList) {
            addText(document,txtName);
        }

        //获取发票内容
        ArrayList<txtName> list = getTxtList(order, bill, product,
                trader, ourCompany, sealer,dealer);

        //写入标题后信息
        for (txtName txtName : list) {
            addInnerTxt(document,txtName);
        }

        String url = "01,10,044031600111,25001580,183.82,20161017,05197160245138663193\n";
        Image qrImg = getQrImg(url);
        document.add(qrImg);
        pdfDocument.close();
        Double money = 23234543523.32;
        System.out.println(Money.Turn(money));
        return null;
    }

    //    在document上写入标题的方法
    public static void addText(Document document,txtName txtName) throws IOException {
        Paragraph paragraph = new Paragraph(txtName.getStr())
                .setFont(PdfFontFactory.createFont("./tipFiles/simfang.ttf", PdfEncodings.IDENTITY_H,true))
                .setFontColor(new DeviceRgb(130, 89, 37))
                .setFontSize(12)
                .setFixedPosition(txtName.getX(), txtName.getY(),1000);
        document.add(paragraph);
    }
    //    在document上写入内容的方法
    public static void addInnerTxt(Document document,txtName txtName) throws IOException {
        Paragraph paragraph = new Paragraph(txtName.getStr())
                .setFont(PdfFontFactory.createFont("./tipFiles/simsun.ttf", PdfEncodings.IDENTITY_H,true))
                .setFontColor(new DeviceRgb(0, 0, 0))
                .setFontSize(10)
                .setFixedPosition(txtName.getX(), txtName.getY(),1000);
        document.add(paragraph);
    }
//    获取二维码的方法
    public static Image getQrImg(String url) throws IOException {
        BarcodeQRCode qrCode = new BarcodeQRCode(url);
        java.awt.Image awtImage = qrCode.createAwtImage(java.awt.Color.black, java.awt.Color.WHITE);
        BufferedImage bufferedImage = new BufferedImage(128, 128, BufferedImage.TYPE_INT_RGB);
        Graphics2D graphics = bufferedImage.createGraphics();
        graphics.drawImage(awtImage,0,0,128,128,java.awt.Color.white,null);
        graphics.dispose();
        File file = new File("./tipFiles/QR.png");
        ImageIO.write(bufferedImage,"png",file);
        Image QRimg = new Image(ImageDataFactory.create("./tipFiles/QR.png"));
        QRimg.setFixedPosition(-267f,117f)
                .setMaxHeight(72);
        return QRimg;
    }
    //获取发票信息的方法
    private static ArrayList<txtName> getTxtList(Order order, Bill bill, Products product,
                                                Trader trader, Trader ourCompany, User sealer,
                                                User dealer){
        ArrayList<txtName> list = new ArrayList<>();
        Trader PartyBuy;
        Trader PartySell;
        //判断交易类型,设置甲乙方
        if (order.getType().equals("入库")){
            PartyBuy = ourCompany;
            PartySell = trader;
        }else {
            PartyBuy = trader;
            PartySell = ourCompany;
        }
        //表头信息
        list.add(txtName.set(bill.getBillNum(),34f,7f));//发票代码
        list.add(txtName.set(bill.getInvoicNum(),34f,7f));//发票号码
        list.add(txtName.set(bill.getVerifyNum(),34f,7f));//效验码
        list.add(txtName.set(new SimpleDateFormat("yyyyMMdd")
                .format(bill.getCreated()),34f,7f));//开票日期
        //购买方信息
        list.add(txtName.set(PartyBuy.getName(),34f,7f));//名称
        list.add(txtName.set(PartyBuy.getTaxNum(),34f,7f));//纳税人识别号
        list.add(txtName.set(PartyBuy.getTelephone(),34f,7f));//电话 开户行及账号
        list.add(txtName.set(PartyBuy.getBankName()+"银行："
                +PartyBuy.getAccountNumber(),34f,7f));//电话 开户行及账号
        return list;
    }

    //获取标题的方法
    private static ArrayList<txtName> getTitleList(){
        ArrayList<txtName> txtList = new ArrayList<>();
        txtList.add(txtName.set("发票代码：",160f,160f));
        txtList.add(txtName.set("发票号码：",160f,txtList.get(0).getY()-16));
        txtList.add(txtName.set("开票日期：",160f,txtList.get(1).getY()-16));
        txtList.add(txtName.set("校验码：",160f,txtList.get(2).getY()-16));
        txtList.add(txtName.set("名称：",-245f,88f));
        txtList.add(txtName.set("纳税人识别号：",txtList.get(4).getX(),txtList.get(4).getY()-14));
        txtList.add(txtName.set("地址、电话：",txtList.get(4).getX(),txtList.get(5).getY()-14));
        txtList.add(txtName.set("开户行及账号：",txtList.get(4).getX(),txtList.get(6).getY()-14));
        txtList.add(txtName.set("货物或劳务、服务名称",-265f,30f));
        txtList.add(txtName.set("规格型号",- 125f,txtList.get(8).getY()));
        txtList.add(txtName.set("单位",-60f,txtList.get(8).getY()));
        txtList.add(txtName.set("数量",-10f,txtList.get(8).getY()));
        txtList.add(txtName.set("单价",55f,txtList.get(8).getY()));
        txtList.add(txtName.set("金额",125f,txtList.get(8).getY()));
        txtList.add(txtName.set("税率",174f,txtList.get(8).getY()));
        txtList.add(txtName.set("税额",225f,txtList.get(8).getY()));
        txtList.add(txtName.set("合    计",-230f,-83f));
        txtList.add(txtName.set("价格合计（大写）",-250f,-103f));
        txtList.add(txtName.set("（小写）",110f,-103f));
        txtList.add(txtName.set("名称：",-245f,-120f));
        txtList.add(txtName.set("纳税人识别号：",txtList.get(19).getX(),txtList.get(19).getY()-14));
        txtList.add(txtName.set("地址、电话：",txtList.get(19).getX(),txtList.get(20).getY()-14));
        txtList.add(txtName.set("开户行及账号：",txtList.get(19).getX(),txtList.get(21).getY()-14));
        txtList.add(txtName.set("收款人：",-255f,-185f));
        txtList.add(txtName.set("复核：",txtList.get(23).getX()+120f,txtList.get(23).getY()));
        txtList.add(txtName.set("开票人：",txtList.get(24).getX()+120f,txtList.get(23).getY()));
        txtList.add(txtName.set("销售方：（章）",txtList.get(25).getX()+120f,txtList.get(23).getY()));
        txtList.add(txtName.set("购",-266f,85f));
        txtList.add(txtName.set("买",txtList.get(27).getX(),txtList.get(27).getY()-16));
        txtList.add(txtName.set("方",txtList.get(27).getX(),txtList.get(28).getY()-16));
        txtList.add(txtName.set("销",txtList.get(27).getX(),-125f));
        txtList.add(txtName.set("售",txtList.get(27).getX(),txtList.get(30).getY()-16));
        txtList.add(txtName.set("方",txtList.get(27).getX(),txtList.get(31).getY()-16));
        txtList.add(txtName.set("密",58f,85f));
        txtList.add(txtName.set("码",txtList.get(33).getX(),txtList.get(33).getY()-16));
        txtList.add(txtName.set("区",txtList.get(33).getX(),txtList.get(34).getY()-16));
        txtList.add(txtName.set("备",txtList.get(33).getX(),-125f));
        txtList.add(txtName.set("注",txtList.get(33).getX(),txtList.get(36).getY()-32));
        return txtList;
    }
}

@Data
@Accessors(chain = true)
class txtName{
    private String str;
    private Float x;
    private Float y;
    public static txtName set(String str,Float x,Float y){
        return new txtName().setStr(str).setX(x).setY(y);
    }
}

//double类型转换为中文大写
class Money {
    static String moneyD =new String();
    static String moneyBefore=new String() ;
    static String moneyAfter=new String();
    static StringBuffer moneyA = new StringBuffer();
    public static String getTurns(int i) {
        switch (i) {
            case 2 :
                moneyD = "拾";
                break;
            case 3 :
                moneyD = "佰";
                break;
            case 4 :
                moneyD = "仟";
                break;
            case 5 :
                moneyD = "万";
                break;
            case 6 :
                moneyD = "拾";
                break;
            case 7 :
                moneyD = "佰";
                break;
            case 8 :
                moneyD = "仟";
                break;
            case 9 :
                moneyD = "亿";
                break;
            case 10 :
                moneyD = "拾";
                break;
            case 11 :
                moneyD = "佰";
                break;
            case 12 :
                moneyD = "仟";
                break;
        }
        return moneyD.toString();
    }
    public static String getTurnMoneyWord(String s) {
        switch (Integer.parseInt(s)) {
            case 0 :
                return "零";
            case 1 :
                return "壹";
            case 2 :
                return "贰";
            case 3 :
                return "叁";
            case 4 :
                return "肆";
            case 5 :
                return "伍";
            case 6 :
                return "陆";
            case 7 :
                return "柒";
            case 8 :
                return "捌"; }
        return "玖";
    }

    public static String getTurnMoneys(String money) {
        try {
            if (money.indexOf("-") != -1) {
                moneyA.append("负");
                money = money.substring(money.indexOf("-") + 1, money.length());
            }
            if (money.indexOf(".") != -1) {
                moneyBefore= money.substring(0, money.indexOf("."));
                moneyAfter = money.substring(money.indexOf(".") + 1, money.length());
            } else {
                moneyBefore = money;
                moneyAfter = "none";
            }
            if (moneyBefore.length() == 1&& moneyBefore.charAt(0) == '0'&& moneyAfter == "none") {
                moneyA.append("零");
                moneyA.append("圆");
            } else {
                for (int i = 0; i < moneyBefore.length(); i++) {
                    if (moneyBefore.charAt(i) != '0') {
                        moneyA.append(getTurnMoneyWord(
                                String.valueOf(
                                        String.valueOf(moneyBefore.charAt(i))).concat("")));
                        if (moneyBefore.length() != i + 1)
                            moneyA.append(getTurns(moneyBefore.length() - i));
                        continue;
                    }
                    if (moneyBefore.length() - i == 5&&( moneyBefore.length() > 5&& moneyBefore.length() <= 9))
                        moneyA.append("万");
                    if (moneyBefore.length() - i == 9&& moneyBefore.length() > 9)
                        moneyA.append("亿");
                    if (moneyBefore.length() != i + 1&& moneyBefore.charAt(i + 1) != '0')
                        moneyA.append("零");
                }
                if (moneyBefore.length() != 1 || moneyBefore.charAt(0) != '0') {
                    moneyA.append("圆");
                }
            }
            if (!moneyAfter.equals("none")) {
                for (int i = 0; i < moneyAfter.length(); i++) {
                    if (i == 0)
                        if (moneyAfter.charAt(i) != '0') {
                            moneyA.append(getTurnMoneyWord(String.valueOf( String.valueOf(
                                    moneyAfter.charAt(i))).concat("")));
                            moneyA.append("角");
                        } else if (moneyBefore.charAt(0) != '0' && moneyAfter.length()>1 && (!moneyAfter.equals("00")))
                            moneyA.append("零");
                    if (i == 1 && moneyAfter.charAt(i) != '0') {
                        moneyA.append(getTurnMoneyWord(String.valueOf(
                                String.valueOf(moneyAfter.charAt(i))).concat(
                                "")));
                        moneyA.append("分");
                    }
                }

            }
            if (moneyAfter.equals("none") || moneyAfter.length() != 2 || moneyAfter.equals("00"))
                moneyA.append("整");
        } catch (Exception exception) {
        }
        return moneyA.toString();
    }
    public static String Turn(Double money) {
        DecimalFormat decimalFormat = new DecimalFormat("###0.00");
        String format = decimalFormat.format(money);
        System.out.println(format);
        return getTurnMoneys(format);
    }
}